package com.wlanauth.core.criteria;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
/**
 * 通用查询
 * @author zz
 * @date 2012-5-9
 * @email charles.zz.life@gmail.com
 * 
 * 
 * 使用方法如下
 * GeneralCriteria criteria = new GeneralCriteria(RadAcct.class);
 * criteria.setStart(1);
 * criteria.setLimit(5);
 * GeneralCriteriaQuery<RadAcct> query = new GeneralCriteriaQuery<RadAcct>();
 * GeneralCriteriaResult<RadAcct> result = query.execute(criteria);
 * System.out.println("result:"+result.getTotal()+",list:"+result.getData().size());
 * 
 */
public class GeneralCriteriaQuery extends HibernateTemplate implements ApplicationContextAware {
	
	private static String sessionFactoryBeanName ;
	private static SessionFactory sf;
	
	@SuppressWarnings({ "unchecked" })
	public <T extends Object> GeneralCriteriaResult<T> execute(final GeneralCriteria criteria) {
		//刷新会话
		flushSession();
		GeneralCriteriaResult<T> result = new GeneralCriteriaResult<T>();
		
		Integer total = -1;
		//查询总数
		if(!criteria.isDataOnly()){
				
			total= (Integer) this.execute(new HibernateCallback(){
	
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					Criteria queryCountCriteria = criteria.getExecutableCriteria(session);
						queryCountCriteria.setProjection(Projections.rowCount());
						Integer total = ((Integer)queryCountCriteria.uniqueResult());
						queryCountCriteria.setProjection(null);
						return total==null?0:total;
				}
				
			});
		}
		List<T> data = this.findByCriteria(criteria,
				criteria.getStart(), criteria.getLimit());
		result.setData(data);
		result.setTotal(total);
		return result;
	}
	@SuppressWarnings("unchecked")
	public <T extends Object> List<T> execute(final DetachedCriteria criteria) {
		//刷新会话
		flushSession();
		List<T> list = (List<T>) this.execute(new HibernateCallback(){

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				return criteria.getExecutableCriteria(session).list();
			}
			
		});
		return list;
	}
	
	private void flushSession(){
		this.setSessionFactory(sf);
	}
	public void setSessionFactoryBeanName(String sessionFactoryBeanName) {
		GeneralCriteriaQuery.sessionFactoryBeanName = sessionFactoryBeanName;
	}
	

	public void setApplicationContext(ApplicationContext ctx)
			throws BeansException {
		
		sf = (SessionFactory) ctx.getBean(GeneralCriteriaQuery.sessionFactoryBeanName);
		flushSession();
		
	}
	
	
	

}
